from decimal import Decimal

from django_redis import get_redis_connection
from rest_framework import serializers
from django.db import transaction
from goods.models import SKU
from orders.models import OrderInfo, OrderGoods
from datetime import datetime


class SkuSerializers(serializers.ModelSerializer):
    # 指定返回商品数量
    count = serializers.IntegerField(read_only=True)

    class Meta:
        model = SKU
        fields = '__all__'


class OrderSerializers(serializers.Serializer):
    # 指定返回商品数量
    skus = SkuSerializers(many=True)
    # decimal_places 保留多少为小数  max_digits 最大多少位
    freight = serializers.DecimalField(max_digits=10, decimal_places=2)


'''
freight:100

skus:[

{
    count:10,

    name:华为

}，
{

    count:10,
    name:iphone
}
]

'''


class SaveOrderSerializers(serializers.ModelSerializer):
    class Meta:
        model = OrderInfo
        fields = ('address', 'pay_method', 'order_id')
        read_only_fields = ('order_id',)
        extra_kwargs = {
            'address': {
                'write_only': True
            },
            'pay_method': {
                'write_only': True
            },
        }

    # @transaction.atomic
    def create(self, validated_data):

        # 获取用户，订单编号，收货地址，支付方式
        user = self.context['request'].user

        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + '%06d' % user.id

        address = validated_data['address']
        pay_method = validated_data['pay_method']

        with transaction.atomic():

            # 创建保存点
            save_point = transaction.savepoint()
            try:
                # 订单基本信息表的生成
                Order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=0,
                    total_amount=Decimal(0),
                    freight=Decimal(10),
                    pay_method=pay_method,
                    status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'] if pay_method == OrderInfo.PAY_METHODS_ENUM[
                        'CASH'] else OrderInfo.ORDER_STATUS_ENUM['UNPAID']
                )

                # 查询选中状态的商品信息
                conn = get_redis_connection('cart')
                # 获取商品数量  sku_id count
                sku_count = conn.hgetall('cart_%s' % user.id)

                cart = {}
                for sku_id, count in sku_count.items():
                    cart[int(sku_id)] = int(count)

                # 获取选中状态的sku_id
                sku_ids = conn.smembers('cart_selecte_%s' % user.id)

                # 根据缓存中给存储的sku_id查询商品对象
                # skus = SKU.objects.filter(id__in=sku_ids)

                for sku_id in sku_ids:

                    while True:
                        # 查询商品
                        sku = SKU.objects.get(id=sku_id)
                        # 遍历商品信息
                        old_stock = sku.stock  # 原始库存  python  0
                        old_sales = sku.sales  # 原始销量
                        cart_count = cart[sku.id]  # 购买数量 python1 10
                        # 判断每一商品购买的库存是否充足
                        if cart_count > old_stock:
                            raise serializers.ValidationError('商品库存不足')


                        # 修改sku商品库存和销量
                        new_stock = old_stock - cart_count  # 新库存
                        new_sales = old_sales + cart_count  # 新销量

                        # sku.stock=new_stock  # new——stock = 0
                        # sku.sales=new_sales
                        # sku.save()
                        ret = SKU.objects.filter(id=sku_id, stock=old_stock).update(stock=new_stock, sales=new_sales)
                        if ret == 0:
                            continue

                        # 修改spu中总销量
                        sku.goods.sales += cart_count
                        sku.goods.save()

                        # 修改order基本信息表中的商品总量和总价
                        Order.total_amount += (sku.price * cart_count)
                        Order.total_count += cart_count

                        # 生成商品订单信息表
                        OrderGoods.objects.create(
                            order=Order,
                            sku=sku,
                            count=cart_count,
                            price=sku.price
                        )
                        break
                # 添加运费
                Order.total_amount += Order.freight
                Order.save()

            except:
                transaction.savepoint_rollback(save_point)

            else:
                transaction.savepoint_commit(save_point)

                # 删除redis中选中状态的商品
                # 删哈希类型
                conn.hdel('cart_%s' % user.id, *sku_ids)
                # 删除集合
                conn.srem('cart_selecte_%s' % user.id, *sku_ids)

                # 返回order_id
                return Order




